package com.ruoyi.crm.service.impl;

import java.io.Serializable;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.common.enums.AuditStatus;
import com.ruoyi.common.enums.erp.CrmOrderProgessEnum;
import com.ruoyi.common.enums.flow.FlowTypeEnum;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.common.utils.flow.FlowDTO;
import com.ruoyi.common.utils.flow.FlowParamsUtils;
import com.ruoyi.crm.domain.*;
import com.ruoyi.crm.mapper.CrmContractMapper;
import com.ruoyi.crm.service.ICrmCustomerService;
import com.ruoyi.crm.service.ICrmOrderCollectPayMoneyService;
import com.ruoyi.crm.service.ICrmOrderService;
import com.ruoyi.crm.utils.ThreadLocalUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.ruoyi.crm.mapper.CrmAcceptanceSheetMapper;
import com.ruoyi.crm.service.ICrmAcceptanceSheetService;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.ObjectUtils;

/**
 * 验收Service业务层处理
 *
 * @author 最帅陈彬彬
 * @date 2024-12-06
 */
@Service
public class CrmAcceptanceSheetServiceImpl extends ServiceImpl<CrmAcceptanceSheetMapper,CrmAcceptanceSheet> implements ICrmAcceptanceSheetService {
    @Autowired
    private CrmAcceptanceSheetMapper crmAcceptanceSheetMapper;

    @Autowired
    private CrmContractMapper crmContractMapper;

    @Autowired
    private ICrmOrderService crmOrderService;

    @Autowired
    private ICrmOrderCollectPayMoneyService crmOrderCollectPayMoneyService;

    @Autowired
    private ICrmCustomerService crmCustomerService;


    /**
     * 查询验收
     *
     * @param id 验收主键
     * @return 验收
     */
    @Override
    public CrmAcceptanceSheet selectCrmAcceptanceSheetById(String id) {
        return crmAcceptanceSheetMapper.selectById(id);
    }

    /**
     * 查询验收列表
     *
     * @param crmAcceptanceSheet 验收
     * @return 验收
     */
    @Override
    public List<CrmAcceptanceSheet> selectCrmAcceptanceSheetList(CrmAcceptanceSheet crmAcceptanceSheet) {
        return crmAcceptanceSheetMapper.selectCrmAcceptanceSheetList(crmAcceptanceSheet);
    }

    /**
     * 新增验收
     *
     * @param crmAcceptanceSheet 验收
     * @return 结果
     */
    @Override
    @Transactional
    public int insertCrmAcceptanceSheet(CrmAcceptanceSheet crmAcceptanceSheet){
        int count = crmContractMapper.selectCount(new LambdaQueryWrapper<CrmContract>()
                .eq(CrmContract::getOrderId, crmAcceptanceSheet.getOrderId())
                .eq(CrmContract::getAuditStatus, AuditStatus.PASS.getCode()));

        CrmOrder order = crmOrderService.getById(crmAcceptanceSheet.getOrderId());

        if (ObjectUtils.isEmpty(order)){
            throw new ServiceException("商机数据不存在，请刷新后重试");
        }

        if (count == 0) {
            throw new ServiceException("请先完善项目合同表, 或合同表未审核通过");
        }

        int count2 = crmOrderCollectPayMoneyService.count(new LambdaQueryWrapper<CrmOrderCollectPayMoney>()
                .eq(CrmOrderCollectPayMoney::getProjectId, crmAcceptanceSheet.getProjectId())
                .eq(CrmOrderCollectPayMoney::getMoneyType, "1"));

        if (count2 == 0){
            throw new ServiceException("请先前往收付款管理中，完善收款信息!");
        }


        crmAcceptanceSheet.setCreateTime(DateUtils.getNowDate());
        crmAcceptanceSheet.setCreateBy(SecurityUtils.getUsername());
        //如果选择无
        if(crmAcceptanceSheet.getRequired().equals("2")){
            // 修改商机进度，立项成功则进度为验收
            order.setOrderId(crmAcceptanceSheet.getOrderId());
            order.setProgess(CrmOrderProgessEnum.INSPECTION_COMPLETED.getCode());
            crmOrderService.updateCrmOrderInfo(order);
            crmAcceptanceSheet.setAuditStatus(AuditStatus.PASS.getCode());
            return baseMapper.insert(crmAcceptanceSheet);
        }
        crmAcceptanceSheet.setId(IdWorker.getIdStr());
        try {
            ThreadLocalUtils.set(FlowTypeEnum.FLOW_ACCEPTANCE_SHEET.getInfo() + ":" + crmAcceptanceSheet.getId(), crmAcceptanceSheet);
            FlowParamsUtils.start(crmAcceptanceSheet, "flow-acceptanceSheet", crmAcceptanceSheet.getId());
            if (AuditStatus.AWAIT_AUDIT.getCode().equals(crmAcceptanceSheet.getAuditStatus())){
                FlowParamsUtils.submit(crmAcceptanceSheet);
            }

            return baseMapper.insert(crmAcceptanceSheet);
        } finally {
            ThreadLocalUtils.remove(FlowTypeEnum.FLOW_ACCEPTANCE_SHEET.getInfo() + ":" + crmAcceptanceSheet.getId());
        }

    }

    /**
     * 修改验收
     *
     * @param crmAcceptanceSheet 验收
     * @return 结果
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public int updateCrmAcceptanceSheet(CrmAcceptanceSheet crmAcceptanceSheet) {
        crmAcceptanceSheet.setUpdateTime(DateUtils.getNowDate());
        crmAcceptanceSheet.setUpdateBy(SecurityUtils.getUsername());
        CrmAcceptanceSheet sheet = baseMapper.selectById(crmAcceptanceSheet.getId());

        if (ObjectUtils.isEmpty(sheet)){
            throw new ServiceException("项目验收不存在，请刷新后重试");
        }

        try {
            ThreadLocalUtils.set(FlowTypeEnum.FLOW_ACCEPTANCE_SHEET.getInfo() + ":" + crmAcceptanceSheet.getId(), crmAcceptanceSheet);

            // 如果项目处于待提交状态，则直接修改
            if (AuditStatus.AWAIT_SUBMIT.getCode().equals(sheet.getAuditStatus())){

                // 如果新立项状态为提交，则执行流程
                if (AuditStatus.AWAIT_AUDIT.getCode().equals(crmAcceptanceSheet.getAuditStatus())) {
                    FlowParamsUtils.submit(crmAcceptanceSheet);
                }

                return baseMapper.updateById(crmAcceptanceSheet);
            }


            // 如果当前项目处于待审核也直接修改
            if (AuditStatus.AWAIT_AUDIT.getCode().equals(sheet.getAuditStatus())){

                // 如果新结算状态为暂存，则删除流程
                if (AuditStatus.AWAIT_SUBMIT.getCode().equals(crmAcceptanceSheet.getAuditStatus())) {
                    FlowParamsUtils.remove(sheet.getInstanceId());
                    // 开启新流程
                    FlowParamsUtils.start(crmAcceptanceSheet, "flow-acceptanceSheet", crmAcceptanceSheet.getId());
                }

                return baseMapper.updateById(crmAcceptanceSheet);
            }

            // 在审核中，则删除原来流程
            if (AuditStatus.IN_AUDIT.getCode().equals(crmAcceptanceSheet.getAuditStatus())){
                FlowParamsUtils.remove(crmAcceptanceSheet.getInstanceId());
            }

            // 开启新流程
            FlowParamsUtils.start(crmAcceptanceSheet, "flow-acceptanceSheet", crmAcceptanceSheet.getId());

            // 如果新立项状态为提交，则执行流程
            if (AuditStatus.AWAIT_AUDIT.getCode().equals(crmAcceptanceSheet.getAuditStatus())) {
                FlowParamsUtils.submit(crmAcceptanceSheet);
            }
            return baseMapper.updateById(crmAcceptanceSheet);
        } finally {
            ThreadLocalUtils.remove(FlowTypeEnum.FLOW_ACCEPTANCE_SHEET.getInfo() + ":" + crmAcceptanceSheet.getId());
        }
    }

    /**
     * 批量删除验收
     *
     * @param ids 需要删除的验收主键
     * @return 结果
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public int deleteCrmAcceptanceSheetByIds(String[] ids) {
        List<CrmAcceptanceSheet> crmAcceptanceSheets = baseMapper.selectBatchIds(Arrays.asList(ids));
        List<Long> instanceIdList = crmAcceptanceSheets.stream().map(CrmAcceptanceSheet::getInstanceId).collect(Collectors.toList());
        FlowParamsUtils.remove(instanceIdList);
        return baseMapper.deleteBatchIds(Arrays.asList(ids));
    }

    /**
     * 删除验收信息
     *
     * @param id 验收主键
     * @return 结果
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int deleteCrmAcceptanceSheetById(String id) {
        return crmAcceptanceSheetMapper.deleteById(id);
    }

    /**
     * 审核
     * @param crmAcceptanceSheet
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public int audit(CrmAcceptanceSheet crmAcceptanceSheet) {
        CrmAcceptanceSheet sheet = baseMapper.selectById(crmAcceptanceSheet.getId());


        if (ObjectUtils.isEmpty(sheet)){
            throw new ServiceException("项目验收数据不存在，请刷新后重试");
        }

        CrmOrder order = crmOrderService.getById(crmAcceptanceSheet.getOrderId());

        if (ObjectUtils.isEmpty(order)){
            throw new ServiceException("商机数据不存在，请刷新后重试");
        }

        FlowParamsUtils.skip(crmAcceptanceSheet, "");

        if (AuditStatus.PASS.getCode().equals(crmAcceptanceSheet.getAuditStatus())){
            // 修改商机进度，立项成功则进度为已验收
            order.setOrderId(crmAcceptanceSheet.getOrderId());
            order.setProgess(CrmOrderProgessEnum.INSPECTION_COMPLETED.getCode());
            crmOrderService.updateCrmOrderInfo(order);
        }
        return baseMapper.updateById(crmAcceptanceSheet);
    }

    @Override
    public FlowDTO conversionObjByLocal(Serializable id) {
        CrmAcceptanceSheet crmAcceptanceSheet = ThreadLocalUtils.get(FlowTypeEnum.FLOW_ACCEPTANCE_SHEET.getInfo() + ":" + id);
        CrmCustomer customer = crmCustomerService.getById(crmAcceptanceSheet.getCustomerId());
        CrmOrder crmOrder = crmOrderService.getById(crmAcceptanceSheet.getOrderId());
        crmAcceptanceSheet.setCustomerName(customer.getCustomerName());
        crmAcceptanceSheet.setOrderName(crmOrder.getOrderName());
        FlowDTO flowDTO = this.buildFlowDTO(crmAcceptanceSheet);
        return flowDTO;
    }

    @Override
    public FlowDTO conversionObj(Serializable id) {
        CrmAcceptanceSheet crmAcceptanceSheets = baseMapper.getById(id);
        FlowDTO flowDTO = this.buildFlowDTO(crmAcceptanceSheets);
        return flowDTO;
    }


    private FlowDTO buildFlowDTO(CrmAcceptanceSheet crmAcceptanceSheets){
        FlowDTO flowDTO = new FlowDTO(crmAcceptanceSheets);
        Map<String, Object> businessValue = flowDTO.getBusinessValue();
        businessValue.put("项目名称", crmAcceptanceSheets.getOrderName());
        businessValue.put("客户名称", crmAcceptanceSheets.getCustomerName());
        businessValue.put("验收时间", DateUtils.parseDateToStr("yyyy-MM-dd HH:mm:ss", crmAcceptanceSheets.getReceptionTime()));
        return flowDTO;
    }
}
